package cn.likun.kit.validate;

import java.lang.reflect.Array;
import java.util.regex.Pattern;

/**
 * <p>空值校验工具</p>
 * <p>通用的校验工具类</p>
 * <p>支持自定义空值校验</p>
 *@version 1.0
 */
public class ValidateCommons {
	
	private ValidateCommons() {}
	
	/**邮箱正则表达式*/
	public static final String MATCH_RULE_EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
	
	/**
	 * <p>判断对象是否为空</p>
	 * <p>isStrictlyValidate 为 false 时 , 只与 null 进行比较</p>
	 * <p>isStrictlyValidate 为 true 时 , 如果不为 null ,则 类型为 String时,空白字符为空</p>
	 * <p>ruleRegex 不为空时 , obj与ruleRegex做正则表达式为空判断 </p>
	 * <p>如果 obj 既不是String类型,也不是Number类型,则调用obj的size方法判断是'0'则为空</p>
	 * @param obj 待校验对象
	 * @param isStrictlyValidate 是否使用严格校验
	 * @param ruleRegex  null:不使用 [ 为空正则表达式  ] , 非null:使用  [ 为空正则表达式  ] 
	 * @return
	 */
	public static boolean isEmpty(Object obj , boolean isStrictlyValidate , String  ruleRegex) {
		
		if (null == obj) {
			return true;
		}
		if (isStrictlyValidate) {
			Class<?> clazz = obj.getClass();
			if (clazz.isArray()) {
				if (Array.getLength(obj) == 0) {
					return true;
				}
			}
			Class<?> rootClass = getRootClass(clazz);
			String className = rootClass.getName();
			try {
				if (String.class.getName().equals(className)) {
					Object str = rootClass.getMethod("trim").invoke(obj);
					String lengthStr = String.valueOf(rootClass.getMethod("length").invoke(str));
					if (Integer.valueOf(lengthStr) <= 0) {
						return true;
					}
					if (ruleRegex != null) {
						if (Pattern.matches(ruleRegex, String.valueOf(obj))) {
							return true;
						}
					}
				} else if (Number.class.getName().equals(className)) {
					if (ruleRegex != null) {
						if (Pattern.matches(ruleRegex, String.valueOf(obj))) {
							return true;
						}
					}
				} else {
					String sizeStr = String.valueOf(rootClass.getMethod("size").invoke(obj));
					if (Integer.valueOf(sizeStr) == 0) {
						return true;
					}
				}
			} catch (Exception e) {
				return false;
			}
		} 
		
		return false;
	}
	/**
	 * <p>判断对象是否为空</p>
	 * <p>null or String.trim()='' or obj.size=0  返回true</p>
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object obj) {
		return isEmpty(obj, true, null);
	}
	/**
	 * <p>判断对象是否为空</p>
	 * <p>null or String.trim()='' or obj.size=0  就为空</p>
	 * @param obj
	 * @return
	 */
	public static boolean isNotEmpty(Object obj) {
		return !isEmpty(obj);
	}
	/***
	 * <p>判断对象是否为空</p>
	 * <p>isStrictlyValidate 为 false 时 , 只与 null 进行比较</p>
	 * <p>isStrictlyValidate 为 true 时 , 如果不为 null ,则 类型为 String时,空白字符为空</p>
	 * <p>ruleRegex 不为空时 , obj与ruleRegex做正则表达式为空判断 </p>
	 * <p>如果 obj 既不是String类型,也不是Number类型,则调用obj的size方法判断是'0'则为空</p>
	 * @param obj
	 * @param isStrictlyValidate
	 * @param ruleRegex
	 * @return
	 */
	public static boolean isNotEmpty(Object obj,Boolean isStrictlyValidate, String ruleRegex) {
		return !isEmpty(obj, isStrictlyValidate, ruleRegex);
	}
	/**
	 * <p>根据规则进行正则表达式校验</p>
	 * @param str
	 * @param rule
	 * @return
	 */
	public static boolean matchRule(String str,String rule) {
		if (ValidateCommons.isEmpty(str)) {
			return false;
		}
		if (Pattern.matches(rule, str)) {
			return true;
		}
		return false;
	}
	
	
	/**
	 * 取顶级父类 , 非Object
	 * @param clazz 
	 * @return 顶级父类 
	 */
	private static Class<?> getRootClass(Class<?> clazz) {
		String rootClass = Object.class.getName();
		Class<?> superClass = clazz.getSuperclass();
		if (superClass != null) {
			String className = superClass.getName();
			if (!rootClass.equals(className)) {
				clazz = getRootClass(superClass);
			}
		}
		return clazz ;
	}
}
